package cn.sunxyz.data.support;

import cn.sunxyz.common.utils.StringUtil;
import cn.sunxyz.common.utils.reflect.ClassUtil;
import cn.sunxyz.data.infer.ex.SQLParserException;
import cn.sunxyz.data.orm.domain.ann.Column;
import cn.sunxyz.data.orm.domain.ann.Id;
import cn.sunxyz.data.orm.domain.ann.Table;

import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * Created by yangrd on 2017/6/1.
 */
public class EntitySupport {

    public static String getTableName(Class cls) {
        if (cls.isAnnotationPresent(Table.class)) {
            Table table = (Table) cls.getAnnotation(Table.class);
            return getValue(table.value(), ClassUtil.getShortClassName(cls));
        } else {
            throw new SQLParserException("class:" + cls.getName() + "not found Table Annotation");
        }

    }

    public static Field getIdField(Class cls) {
        if (cls.isAnnotationPresent(Table.class)) {
            Set<Field> annotatedFields = ClassUtil.getAnnotatedFields(cls, Id.class);
            if (!annotatedFields.isEmpty()) {
                return annotatedFields.stream().collect(Collectors.toList()).get(0);
            } else {
                throw new SQLParserException("class:" + cls.getName() + "not found Id Annotation");
            }
        } else {
            throw new SQLParserException("class:" + cls.getName() + "not found Table Annotation");
        }
    }

    public static Set<Field> getColumnFields(Class cls) {
        List<Class<?>> superClzs = ClassUtil.getAllSuperclasses(cls);
        superClzs.add(cls);
        //TOODO 此处需要过滤掉不是column的字段
        return superClzs.stream().flatMap(clz -> Arrays.asList(clz.getDeclaredFields()).stream()).collect(Collectors.toSet());

    }

    //如果field被@Column注解修饰 则获取 @Column#value 否则获取field#name
    public static String getColumn(Field field) {
        return getValue(field.isAnnotationPresent(Column.class) ? field.getAnnotation(Column.class).value() : null, field.getName());
    }

    private static String getValue(String value, String prop) {
        return StringUtil.isNotEmpty(value) ? value : StringUtil.camelToUnderline(prop);
    }
}
